import type { IsEqual } from 'type-fest';

interface Person {
  name: string;
  age: number;
}

interface OwnPerson<T extends Person> extends Person {
  owner: T;
}
/// via https://www.zhihu.com/question/636393410/answer/3447170081
// # ERROR: circle reference
// type Comparable1 = number | Comparable1;

// 对于 同级处 value 处的计算，它是 lazy 的
//  TS 似乎在编译器求值过程中隐式创建了一个 interface, 或者把外部类型都当作 interface 定义来处理
type ComparableType = number | { value: ComparableType };

// via: https://www.zhihu.com/question/636393410/answer/3447170081
// 实际上无论是 interface 还是 type，解析定义体(即 = 右边结构)的过程本身始终不会触发类型展开，
// 唯一触发展开的是处理类型参数时，TS 只有当能够确定一个类型参数的“最终类型”时才会停止对传入类型参数的求值——interface(以及对象字面量类型)都是“最终类型”，
// 而 type 则不是，它们只是“类型别名”。

// 如果换成 interface 呢？(对象字面量类型同理)
interface Wrapped<T> {
  value: T;
}
type Comparable = number | Wrapped<Comparable>;
// TS 尝试得到 Comparable 的类型
// 发现 Wrapped<Comparable>，Wrapped < Comparable > 是个“最终类型”吗？显然是的，因为 Wrapped 是通过 interface 定义的，因此一整个 Wrapped < Comparable > 都得到保留，作为整体不再继续求值
// 最终得到 Comparable 的类型为 number | Wrapped<Comparable>，结束

// type Wrapped2<T> = never;
// 依然报错
// type Comparable2 = number | Wrapped2<Comparable2>;
{
  type UnMerge = { key: string } & { value: number };
  type Merge = { key: string; value: number };

  type _ = IsEqual<Merge, UnMerge>;
  //   ^?
}
type IsUnknown<T> = unknown extends T ? 1 : 0;
type IsAny<T> = 0 extends 1 & T ? 1 : 0;
{
  type a = IsUnknown<any>; // =>
  type g = IsUnknown<1>; // =>
  type b = IsUnknown<unknown>; // =>
  type c = IsUnknown<undefined>; // =>
  type d = IsUnknown<null>; // =>
  type f = IsUnknown<string>; // =>
  type e = IsUnknown<never>; // =>
}
